#ifndef STRATEGY_H
#define STRATEGY_H

#include "PlayHand.h"
#include "Player.h"


class Strategy
{
public:
    Strategy();
    Strategy(Player* player, const Cards& cards);//只针对机器人玩家

    // 1. 制定出牌策略
    Cards makeStrategy();
    // 2. 第一个出牌
    Cards firstPlay();
    // 3. 得到比指定牌型大的牌
    Cards getGreaterCards(PlayHand type);
    // 4. 能大过指定的牌时，判断是出牌还是放行，返回true/false
    bool whetherToBeat(Cards& cards);


    // 5. 找出指定数量（count）的相同点数的牌（point），找出count张点数为point的牌
    Cards findSamePointcards(Card::CardPoint point, int count);
    // 6. 找出所有点数数量为count的牌==>得到一个多张扑克牌的数组
    QVector<Cards> findCardsByCount(int count);
    // 7. 根据点数范围找牌
    Cards getRangeCards(Card::CardPoint begin, Card::CardPoint end);
    // 8. 按牌型找牌，并且指定要找的牌是否要大过指定的牌型
    QVector<Cards> findCardType(PlayHand hand, bool beat);
    QVector<Cards> pickOptimalSeqSingles();

private:
    using function = Cards (Strategy::*)(Card::CardPoint point);//定义函数指针
    struct CardInfo{
        Card::CardPoint begin;
        Card::CardPoint end;
        int extra;//顺子或连对的拓展信息
        bool beat;//是否需要压过对方的牌
        int number;//指定点数的牌的数量（顺子是1，连对是2）
        int base;//最基础的顺子或连对的数量（顺子是5，连对是3）
        function getSeq;//函数指针对象
    };
    //寻找从point起始的所有数量为number的牌组
    QVector<Cards> getCards(Card::CardPoint point, int number);
    //寻找从point起始的所有三带一或二的数组
    QVector<Cards> getTripleSingleOrPair(Card::CardPoint begin, PlayHand::HandType type);
    //寻找从point起始的所有飞机
    QVector<Cards> getPlane(Card::CardPoint begin);
    //寻找从point起始的所有飞机带单牌或双牌
    QVector<Cards> getPlane2SingleOrPair(Card::CardPoint begin, PlayHand::HandType type);
    //寻找从point起始的连对或顺子
    QVector<Cards> getSeqPairOrSeqSingle(CardInfo& info);
    //寻找从point起始的最基础的连对或顺子的回调函数（函数指针调用）
    Cards getbaseSeqPair(Card::CardPoint point);
    Cards getbaseSeqSingle(Card::CardPoint point);
    //寻找从point起始的所有的炸弹
    QVector<Cards> getBomb(Card::CardPoint begin);

    //从指定的牌组中挑选出满足条件的顺子（剩下最少）
    void pickSeqSingle(QVector<QVector<Cards>>& allSeqRecord, const QVector<Cards>& seqSingle,const Cards& cards);


private:
    Player* m_player;
    Cards m_cards;
};

#endif // STRATEGY_H
